BabyOS如何使用WIFI模组
当MCU项目要增加网络通讯功能时可选择支持串口通讯的WIFI模组。
WIFI模组硬件连接比较简单,仅需一路串口便可以使用。
软件方面使用AT指令或私有协议进行配置和收发数据。
BabyOS目标是助力MCU项目的开发,那如何友好的兼容各类模组呢?
以下方案作抛砖引玉之用。
软件方面考虑的点:
① AT指令发送后需要等待回复,裸机如何做到不阻塞的等待
② 多个AT指令实现一个功能配置,如何将功能与AT指令对应
③ 各家的指令有差异,但给上层业务调用的接口要做到统一
④ 模组收到数据后如何抛给上层使用
thirdparty增加pt.h
为了让裸机实现不阻塞的等待,BabyOS thirdparty部分增加PT。为了更方便使用,对宏进行了修改:
#define PT_WAIT_UNTIL_FOREVER(pt, condition)
#define PT_WAIT_UNTIL(pt, condition, timeout)
#define PT_WAIT_WHILE(pt, cond)
#define PT_DELAY_MS(pt, ms)
AT指令的处理便非常方便
static int _bEspMainTask(struct pt *pt)
{
static uint8_t index = 0;
uint16_t retval = 0;
PT_BEGIN(pt);
while (1)
{
if (bEspRunInfo[index].pcmd == NULL)
{
break;
}
if (*(bEspRunInfo[index].pcmd) == NULL)
{
......
break;
}
//发送AT指令
retval = (*(bEspRunInfo[index].pcmd))(index, &bEspRunInfo[index].param);
if (retval > 0)
{
//带有超时时间的等待,等模组的回复
PT_WAIT_UNTIL(pt, bEspRunInfo[index].at_ack.ack == AT_CMD_ACK_DONE, retval);
......
}
......
//非阻塞延时500ms
PT_DELAY_MS(pt, 500);
}
PT_END(pt);
}
增加b_mod_wifi软件模块
增加b_mod_wifi,提供统一的接口给上层调用。
调用bWifiUp
时指定设备号并注册事件处理函数。
b_mod_wifi
产生事件并通过上层注册的处理函数抛出。
b_mod_wifi主要使用bCtl
接口操作设备。因此接入的模组,其驱动需要实现b_driver_cmd.h
里所列的命令:
///////////////////////////////////////////////////////////
// Wifi Module Command & Data Structure
///////////////////////////////////////////////////////////
#define bCMD_WIFI_MODE_STA 0 // none
#define bCMD_WIFI_MODE_AP 1 // bApInfo_t
#define bCMD_WIFI_MODE_STA_AP 2 // bApInfo_t
#define bCMD_WIFI_JOIN_AP 3 // bApInfo_t
#define bCMD_WIFI_MQTT_CONN 4 // bMqttConnInfo_t
#define bCMD_WIFI_MQTT_SUB 5 // bMqttTopic_t
#define bCMD_WIFI_MQTT_PUB 6 // bMqttData_t
#define bCMD_WIFI_LOCAL_TCP_SERVER 7 // bTcpUdpInfo_t
#define bCMD_WIFI_LOCAL_UDP_SERVER 8 // bTcpUdpInfo_t
#define bCMD_WIFI_REMOT_TCP_SERVER 9 // bTcpUdpInfo_t
#define bCMD_WIFI_REMOT_UDP_SERVER 10 // bTcpUdpInfo_t
#define bCMD_WIFI_PING 11 // default www.baidu.com
#define bCMD_WIFI_GET_CONN_STATUS 12 // bWfifiConnStat_t
#define bCMD_WIFI_REG_CALLBACK 13 // bWifiModuleCallback_t
#define bCMD_WIFI_TCPUDP_CLOSE 14 // bTcpUdpInfo_t
#define bCMD_WIFI_TCPUDP_SEND 15 // bTcpUdpData_t
增加b_util_queue
上层调用接口,无法立即返回结果。创建队列,给上层调用的接口实质是往队列里抛数据。b_mod_wifi有循环调用的处理函数。从队列中取数据并处理。
static int _bModWifiTask(struct pt *pt)
{
static bWifiQItem_t item;
void *param = NULL;
int wait = 0;
PT_BEGIN(pt);
while (1)
{
if (bQueuePop(&bModWifiQueue, &item) < 0)
{
return -1;
}
......
if (wait == 1)
{
PT_WAIT_UNTIL_FOREVER(pt, item.handle->result >= 0);
}
if (item.release)
{
item.release(item.param);
}
memset(&item, 0, sizeof(bWifiQItem_t));
}
PT_END(pt);
}
优化b_util_memp
启用b_mod_wifi时会自动启用动态内存的使用。虽然BabyOS尽量不使用动态内存,但这种场景下没有想到更好的方法,所以决定这一部分使用动态内存。先前只实现了简单的内存池分配,将其重写。
调用bMalloc采用First fit的规则划分空间使用。
调用bFree释放空间,并将相邻的空闲块合并成。
void *bMalloc(uint32_t size);
void bFree(void *paddr);
uint32_t bGetFreeSize(void); //获取空闲大小
void bMallocFailedHook(void); //bMalloc失败后的处理,弱函数,用户自行实现
公众号助力DIY
使用BabyOS可以很方便的开发一个带网络功能的小玩意。要想通过手机控制设备还需要服务器和APP。BabyOS都已经提供,方便开发者DIY。
MQTT服务: babyos.cn:1883
关注公众号,每个用户都有唯一的topic,给微信公众号发消息便会自动向主题发布消息。
以上内容作为抛砖引玉,期待开发者接入更多的模组。如有问题、建议或者需求,提在仓库的Issue页面。会依次处理。
目前BabyOS的文档不再以pdf形式提供,最新文档的访问入口:https://babyos.cn/doc/